package cn.wen.javax.crypto;

import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import cn.wen.java.nio.Charset;

/**
 * Title： 加密/解密相关操作（实现类）
 * <p>
 * Description：提供加密/解密处理，可指定其他转换方式。DESede(3DES)需要的输入明文长度、密文长度都是8的整数倍（可以指定填充方式来避免长度不足）。
 * 另外，CBC、CFB都需要初始化向量的参数才能加密、解密，但这是本类不支持的方式，可另外实现AbstractCipher进行支持。
 * <p>
 * Copyright：Copyright (c) 2010-2012
 * 
 * @author <a href="mailto:ct_wen@qq.com">ctwen</a>, 温承瑭
 * @version Revision：1.0 Date：2012/7/13 Description：初完成。
 *          <p>
 */
public class CipherImpl extends AbstractCipher {

    /**
     * <pre>
     * 创建缺省实例。
     * 	转换的名称：DESede/ECB/PKCS5Padding
     * 	密钥算法的标准名称：DESede
     * </pre>
     */
    public CipherImpl() {
	super();
	transformation = "DESede/ECB/PKCS5Padding";
	algorithm = "DESede";
    }

    @Override
    public byte[] decrypt(byte[] src, byte[] key) throws Exception {
	Cipher cipher = getCipher();
	cipher.init(Cipher.DECRYPT_MODE, getKey(key), getSecureRandom(key));
	return cipher.doFinal(src);
    }

    @Override
    public byte[] encrypt(byte[] src, byte[] key) throws Exception {
	Cipher cipher = getCipher();
	cipher.init(Cipher.ENCRYPT_MODE, getKey(key), getSecureRandom(key));
	return cipher.doFinal(src);
    }

    private Cipher getCipher() throws NoSuchAlgorithmException, NoSuchPaddingException {
	return Cipher.getInstance(transformation);
    }

    private Key getKey(byte[] key) {
	return new SecretKeySpec(key, algorithm);
    }

    private SecureRandom getSecureRandom(byte[] key) {
	return new SecureRandom(key);
    }

    public void setKey(String key) throws UnsupportedEncodingException {
	super.setKey(key.getBytes(Charset.UTF_8));
    }

}
